﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TDPSet
{
    public class TDPSet
    {

        const int TdpMax = 30;
        const int TdpMin = 4;
        public static void SetTDP(int watt)
        {
            if (watt < TdpMin) { watt = TdpMin; }
            if (watt > TdpMax) { watt = TdpMax; }
            int argwatt = watt * 1000;
            string execarg = $"--stapm-limit={argwatt} --fast-limit={argwatt} --slow-limit={argwatt}";
            string result = runprocess(execarg);
            Console.WriteLine(result);
            if (!result.Contains("Sucessfully"))
            {
                throw new Exception(result);
            }
        }

        const int GpuMax = 2600;
        const int GpuMin = 200;

        private static readonly int[] gpuFreqs =new int[]{ 
            200,400,550,600,650,700,750,800,850,900,950,1000,
            1050,1100,1150,1200,1250,1300,1350,1400,1450,1500,1550,
            1600,1650,1700,1750,1800,1850,1900,1950,2000,2050,2100,
            2150,2200,2250,2300,2350,2400,2450,2500,2550,2600
        };


        public static void SetGPUClock(int mhz)
        {
            var nearestMhz = 1800;
            for (int i = 0; i < gpuFreqs.Length; i++)
            {
                if (Math.Abs(gpuFreqs[i]-mhz) <= Math.Abs(mhz - nearestMhz))
                {
                    nearestMhz = gpuFreqs[i];
                }
            }

            string execarg = $" --gfx-clk={nearestMhz}";
            string result = runprocess(execarg);
            Console.WriteLine(result); 
            if (!result.Contains("Sucessfully"))
            {
                throw new Exception(result);
            }
        }


        private static string runprocess(string args)
        {
            string programDir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "tool");
            string programName = "ryzenadj.exe";
            ProcessStartInfo psi = new ProcessStartInfo(Path.Combine(programDir,programName), args);
            psi.UseShellExecute = false;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardError = true;
            psi.RedirectStandardInput = true;
            psi.CreateNoWindow = true;
            psi.WorkingDirectory = programDir;
            var process = Process.Start(psi);
            return process.StandardOutput.ReadToEnd();
        }
    }
}
